home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / visulztn / saoimage / saoimage.lha / btnlib / remote.c < prev    next >
C/C++ Source or Header  |  1990-04-20  |  11KB  |  301 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /*
  6.  * Module:    remote.c (Remote Control)
  7.  * Project:    PROS -- ROSAT RSDC
  8.  * Purpose:    Simulate buttonbox event
  9.  * Subroutine:    PushButton()            returns: int
  10.  * Subroutine:    TouchButton()            returns: int
  11.  * Subroutine:    ReleaseButton()            returns: int
  12.  * Subroutine:    SetToggleButton()        returns: int
  13.  * Subroutine:    DisableButton()            returns: int
  14.  * Subroutine:    EnableButton()            returns: int
  15.  * Subroutine:    ButtonNumber()            returns: int
  16.  * Subroutine:    ButtonStatus()            returns: int
  17.  * Xlib calls:    XSelectInput()
  18.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  19.  *        You may do anything you like with this file except remove
  20.  *        this copyright.  The Smithsonian Astrophysical Observatory
  21.  *        makes no representations about the suitability of this
  22.  *        software for any purpose.  It is provided "as is" without
  23.  *        express or implied warranty.
  24.  * Modified:    {0} Michael VanHilst    initial version        31 March 1989
  25.  *        {1} Jay Travisano (STScI) VMS,IMTOOL changes    10 Nov   1989
  26.  *        {n} <who> -- <does what> -- <when>
  27.  */
  28.  
  29. #include <stdio.h>    /* get stderr */
  30. #include <X11/Xlib.h>    /* needed by Buttons.h */
  31. #include "buttons.h"
  32.  
  33. #if VMS && IMTOOL
  34. extern void XZ_ast();
  35. extern int  XZ_efn;
  36. #endif
  37.  
  38. /*
  39.  * Subroutine:    PushButton
  40.  * Purpose:    Handle buttonbox behavior to simulate a mouse button being
  41.  *        pressed while the mouse cursor is in a buttonbox button
  42.  * Returns:    1 if able to find button and button function, else 0
  43.  * Called by:    Application program
  44.  * Uses:    btn_PushButton() in PushButton.c
  45.  * Xlib calls:    none
  46.  * Post-state:    Records updated, submenus replaced, buttons highlighted
  47.  * Note:    detail=(event.xbutton.button<<16)|(event.xbutton.state&0xffff)
  48.  * Note:    event filtering to select a response is detail&mask==reference
  49.  */
  50. int PushButton ( buttonbox, btn, mouse_btn, state, mapping )
  51.      ButtonBox buttonbox;    /* i: box which contains this button */
  52.      int btn;            /* i: button identifying index */
  53.      int mouse_btn;        /* i: mouse button: event.xbutton.button */
  54.      int state;            /* i: modifier|button: event.xbutton.state */
  55.      int mapping;        /* i: indicate whether to map submenus */
  56. {
  57.   int btn_PushButton();
  58.  
  59.   /* is the button index in error? */
  60.   if( (btn < 0) || (btn >= buttonbox->btn_cnt) ) {
  61.     (void)fprintf(stderr,"WARNING: pressed button not a button: %d\n", btn);
  62.     return( 0 );
  63.   }
  64.   return( btn_PushButton(buttonbox, btn, mouse_btn, state, mapping) );
  65. }
  66.  
  67. /*
  68.  * Subroutine:    TouchButton
  69.  * Purpose:    Do as if a mouse button is clicked and released in a button
  70.  * Returns:    1 if able to find button and button function, else 0
  71.  * Called by:    Application program
  72.  * Uses:    btn_PushButton() in PushButton.c, ReleaseButton()
  73.  * Xlib calls:    none
  74.  * Post-state:    Records updated, submenus replaced, buttons highlighted if
  75.  *        appropriate
  76.  */
  77. int TouchButton ( buttonbox, btn, mouse_btn, state, mapping )
  78.      ButtonBox buttonbox;    /* i: box which contains this button */
  79.      int btn;            /* i: button identifying index */
  80.      int mouse_btn;        /* i: mouse button: event.xbutton.button */
  81.      int state;            /* i: modifier|button: event.xbutton.state */
  82.      int mapping;        /* i: indicate whether to map submenus */
  83. {
  84.   int btn_PushButton();
  85.   int ReleaseButton();
  86.  
  87.   /* is the button index in error? */
  88.   if( (btn < 0) || (btn >= buttonbox->btn_cnt) ) {
  89.     (void)fprintf(stderr,"WARNING: touched button not a button: %d\n", btn);
  90.     return( 0 );
  91.   }
  92.   if( btn_PushButton(buttonbox, btn, mouse_btn, state, mapping) == 0 )
  93.     return( 0 );
  94.   (void)ReleaseButton (buttonbox, btn);
  95.   return( 1 );
  96. }
  97.  
  98. /*
  99.  * Subroutine:    ReleaseButton
  100.  * Purpose:    Do as if the mouse button which was down is released in a
  101.  *        button
  102.  * Returns:    1 if able to find button and it was being pressed, else 0
  103.  * Called by:    Application program
  104.  * Uses:    btn_ReleaseButton() in PushButton.c
  105.  * Uses:    btn_DrawButton() in DrawButton.c
  106.  * Xlib calls:    none
  107.  * Post-state:    Records updated and buttons highlighted if appropriate
  108.  */
  109. int ReleaseButton ( buttonbox, btn )
  110.      ButtonBox buttonbox;    /* i: box which contains this button */
  111.      int btn;            /* i: button identifying index */
  112. {
  113.   int type;            /* l: response function type */
  114.   void btn_ReleaseButton(), btn_DrawButton();
  115.  
  116.   /* is the button index in error? */
  117.   if( (btn < 0) || (btn >= buttonbox->btn_cnt) ) {
  118.     (void)fprintf(stderr,"WARNING: released button not a button: %d\n", btn);
  119.     return( 0 );
  120.   }
  121.   if( btn != buttonbox->down_btn ) {
  122.     (void)fprintf(stderr, "WARNING: releasing button which is not down\n");
  123.     return( 0 );
  124.   }
  125.   type = buttonbox->buttons[btn].feel->function[buttonbox->down_btn_func];
  126.   /* do all the book-keeping chores (and handle BTNCoWhile) */
  127.   btn_ReleaseButton(buttonbox, type, btn);
  128.   /* draw the button in its released state (if different) */
  129.   if( (type == BTNWhile) || (type == BTNOneShot) )
  130.     btn_DrawButton(&buttonbox->buttons[btn]);
  131.   return( 1 );
  132. }
  133.  
  134. /*
  135.  * Subroutine:    SetToggleButton
  136.  * Purpose:    Set a toggle button to indicate the indicated state
  137.  * Returns:    0 if unable to find button and its toggle function, 2 if it
  138.  *        changed state from what it was, else 1
  139.  * Called by:    Application program
  140.  * Uses:    btn_PushButton() in PushButton.c, ReleaseButton()
  141.  * Xlib calls:    none
  142.  * Post-state:    Records updated and buttons (un)highlighted as appropriate
  143.  */
  144. int SetToggleButton ( buttonbox, btn, status )
  145.      ButtonBox buttonbox;    /* i: box which contains this button */
  146.      int btn;            /* i: button identifying index */
  147.      int status;        /* i: 1 for on, 0 for off */
  148. {
  149.   int fnum;
  150.   int TouchButton(), ReleaseButton(), btn_PushButton();
  151.  
  152.   /* is the button index in error? */
  153.   if( (btn < 0) || (btn >= buttonbox->btn_cnt) ) {
  154.     (void)fprintf(stderr,"WARNING: toggled button not a button: %d\n", btn);
  155.     return( 0 );
  156.   }
  157.   /* note which button option it is */
  158.   for( fnum = 0; fnum < buttonbox->buttons[btn].feel->nfunctions; ++fnum )
  159.     if( buttonbox->buttons[btn].feel->function[fnum] == BTNToggle )
  160.       break;
  161.   if( fnum >= buttonbox->buttons[btn].feel->nfunctions ) {
  162.     (void)fprintf(stderr,"WARNING: set-toggle on non-toggle button: %d\n",btn);
  163.     return( 0 );
  164.   }
  165.   if( status != buttonbox->buttons[btn].selected ) {
  166.     int ref;
  167.  
  168.     /* touch button, mapping arg only applies to mode buttons */
  169.     ref = buttonbox->buttons[btn].feel->reference[fnum];
  170.     if( btn_PushButton(buttonbox, btn, ref >> 16, ref & 0xffff, 0) != 0 )
  171.       (void)ReleaseButton(buttonbox, btn);
  172.     return( 2 );
  173.   }
  174.   return( 1 );
  175. }
  176.  
  177. /*
  178.  * Subroutine:    DisableButton
  179.  * Purpose:    Render a button unchangeable (make its basic function NoOp)
  180.  * Returns:    1 if able to find button, else 0
  181.  * Xlib calls:    XSelectInput()
  182.  * Called by:    Application program
  183.  * Note:    If button is to change state, application should call
  184.  *        a different routine to do so before calling this one
  185.  * Note:    Highlighting state is unchanged, but occupation is undone
  186.  * Note:    Only affects function 0 (the primary function)
  187.  */
  188. int DisableButton ( buttonbox, btn )
  189.      ButtonBox buttonbox;    /* i: box which contains this button */
  190.      int btn;            /* i: button identifying index */
  191. {
  192.   void btn_DrawButton();
  193.  
  194.   /* is the button index in error? */
  195.   if( (btn < 0) || (btn >= buttonbox->btn_cnt) ) {
  196.     (void)fprintf(stderr,"WARNING: disable button not a button: %d\n", btn);
  197.     return( 0 );
  198.   }
  199.   if( buttonbox->buttons[btn].occupied ) {
  200.     buttonbox->buttons[btn].occupied = 0;
  201.     btn_DrawButton(&buttonbox->buttons[btn]);
  202.   }
  203. #if VMS && IMTOOL
  204.   XSelectAsyncInput(buttonbox->display, buttonbox->buttons[btn].wndwID,
  205.             ExposureMask | ButtonPressMask | ButtonReleaseMask,
  206.             XZ_ast, XZ_efn);
  207. #endif
  208.   XSelectInput(buttonbox->display, buttonbox->buttons[btn].wndwID,
  209.            ExposureMask | ButtonPressMask | ButtonReleaseMask);
  210.   buttonbox->buttons[btn].feel->function[0] = BTNNoOp;
  211.   return( 1 );
  212. }
  213.  
  214. /*
  215.  * Subroutine:    EnableButton
  216.  * Purpose:    Enable a button which was previously a NoOp
  217.  * Returns:    1 if able to find button, else 0
  218.  * Xlib calls:    XSelectInput()
  219.  * Called by:    Application program
  220.  * Note:    Application must know its new function
  221.  * Note:    Only affects function 0 (the primary function)
  222.  */
  223. int EnableButton ( buttonbox, btn, function )
  224.      ButtonBox buttonbox;    /* i: box which contains this button */
  225.      int btn;            /* i: button identifying index */
  226.      int function;        /* i: code for function response type */
  227. {
  228.   /* is the button index in error? */
  229.   if( (btn < 0) || (btn >= buttonbox->btn_cnt) ) {
  230.     (void)fprintf(stderr,"WARNING: enable button not a button: %d\n", btn);
  231.     return( 0 );
  232.   }
  233.   buttonbox->buttons[btn].feel->function[0] = function;
  234.   if( buttonbox->buttons[btn].feel->nfunctions == 0 )
  235.     buttonbox->buttons[btn].feel->nfunctions = 1;
  236. #if VMS && IMTOOL
  237.   XSelectAsyncInput(buttonbox->display, buttonbox->buttons[btn].wndwID,
  238.             ButtonReleaseMask | ButtonPressMask |
  239.             EnterWindowMask | LeaveWindowMask | ExposureMask,
  240.             XZ_ast, XZ_efn);
  241. #endif
  242.   XSelectInput(buttonbox->display, buttonbox->buttons[btn].wndwID,
  243.            ButtonReleaseMask | ButtonPressMask |
  244.            EnterWindowMask | LeaveWindowMask | ExposureMask);
  245.   return( 1 );
  246. }
  247.  
  248. /*
  249.  * Subroutine:    ButtonStatus
  250.  * Purpose:    Return the on/off status of a button
  251.  * Returns:    -1 if button not found, 1 if button is currently selected (on),
  252.  *        0 if button is currently not selected (off)
  253.  * Called by:    Application program
  254.  * Xlib calls:    none
  255.  */
  256. int ButtonStatus ( buttonbox, btn )
  257.      ButtonBox buttonbox;    /* i: box which contains this button */
  258.      int btn;            /* i: button identifying index */
  259. {
  260.   /* is the button index in error? */
  261.   if( (btn < 0) || (btn >= buttonbox->btn_cnt) ) {
  262.     (void)fprintf(stderr,"WARNING: status button not a button: %d\n", btn);
  263.     return( -1 );
  264.   }
  265.   return( buttonbox->buttons[btn].selected );
  266. }
  267.  
  268. /*
  269.  * Subroutine:    ButtonNumber
  270.  * Purpose:    Given panel, a datum and its data array index, identify the
  271.  *        button index
  272.  * Returns:    Identifying index of button in this box, else -1.
  273.  * Called by:    Application program
  274.  * Xlib calls:    none
  275.  * Method:    Check given datum for each button, return index of first one
  276.  *        that matches;
  277.  */
  278. int ButtonNumber ( buttonbox, data_index, datum )
  279.      ButtonBox buttonbox;    /* i: box which contains this button */
  280.      int data_index;        /* i: index position in data field of datum */
  281.      int datum;            /* i: datum to be located */
  282. {
  283.   int btn;            /* i: button identifying index */
  284.  
  285.   for( btn = 0; btn < buttonbox->btn_cnt; btn++ ) {
  286.     if( buttonbox->buttons[btn].feel->data[data_index] == datum )
  287.       return( btn );
  288.   }
  289.   (void)fprintf(stderr, "WARNING: button not found - index: %d, datum %d\n",
  290.         data_index, datum);
  291.   return (-1);
  292. }
  293.                                    
  294.                                                                
  295.                                                                
  296.                                                                
  297.                                                                
  298.                                                                
  299.                                                                
  300.                    
  301.